﻿using Avalonia.Controls;
using FaceCat;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading;
using System.Threading.Tasks;

namespace facecat_avalonia
{
    /// <summary>
    /// 滚动按钮
    /// </summary>
    public class ScrollButtonM : FCButton
    {
        public int m_arrowType = 0;

        /// <summary>
        /// 绘图方法
        /// </summary>
        /// <param name="paint"></param>
        /// <param name="clipRect"></param>
        public override void onPaint(FCPaint paint, FCRect clipRect)
        {
            int width = getWidth(), height = getHeight();
            if (width > 0 && height > 0)
            {
                FCRect drawRect = new FCRect(0, 0, width, height);
                if (m_arrowType == 5)
                {
                    if (this == m_native.getPushedView() || this == m_native.getHoveredView())
                    {
                        paint.fillRoundRect(FCColor.rgb(42, 138, 195), drawRect, 4);
                    }
                    else
                    {
                        if (MyColor.m_style == 0)
                        {
                            paint.fillRoundRect(FCColor.rgb(100, 100, 100), drawRect, 4);
                        }
                        else
                        {
                            paint.fillRoundRect(FCColor.rgb(225, 225, 225), drawRect, 4);
                        }
                    }
                }
                else if (m_arrowType == 6)
                {
                    if (this == m_native.getPushedView())
                    {
                        paint.fillRect(FCColor.rgba(0, 0, 0, 25), drawRect);
                    }
                }
                else
                {
                    if (allowDrag() && this == m_native.getPushedView())
                    {
                        paint.fillRect(FCColor.rgb(42, 138, 195), drawRect);
                    }
                    else
                    {
                        if (MyColor.m_style == 0)
                        {
                            paint.fillRect(FCColor.rgb(100, 100, 100), drawRect);
                        }
                        else
                        {
                            paint.fillRect(FCColor.rgb(220, 220, 220), drawRect);
                        }
                    }
                }
                if (this == m_native.getPushedView())
                {
                    int mw = width / 2, mh = height / 2;
                    FCPoint point1 = new FCPoint();
                    FCPoint point2 = new FCPoint();
                    FCPoint point3 = new FCPoint();
                    int ts = 3;
                    switch (m_arrowType)
                    {
                        case 1:
                            point1.x = mw - ts;
                            point1.y = mh;
                            point2.x = mw + ts;
                            point2.y = mh - ts * 3;
                            point3.x = mw + ts;
                            point3.y = mh + ts * 3;
                            break;
                        case 2:
                            point1.x = mw + ts;
                            point1.y = mh;
                            point2.x = mw - ts;
                            point2.y = mh - ts * 3;
                            point3.x = mw - ts;
                            point3.y = mh + ts * 3;
                            break;
                        case 3:
                            point1.x = mw;
                            point1.y = mh - ts;
                            point2.x = mw - ts * 3;
                            point2.y = mh + ts;
                            point3.x = mw + ts * 3;
                            point3.y = mh + ts;
                            break;
                        case 4:
                            point1.x = mw;
                            point1.y = mh + ts;
                            point2.x = mw - ts * 3;
                            point2.y = mh - ts;
                            point3.x = mw + ts * 3;
                            point3.y = mh - ts;
                            break;
                    }
                    FCPoint[] points = new FCPoint[3];
                    points[0] = point1;
                    points[1] = point2;
                    points[2] = point3;
                    paint.fillPolygon(FCColor.rgb(0, 0, 0), points);
                }
            }
        }

        /// <summary>
        /// 绘制边线方法
        /// </summary>
        /// <param name="paint"></param>
        /// <param name="clipRect"></param>
        public override void onPaintBorder(FCPaint paint, FCRect clipRect)
        {
            //base.onPaintBorder(paint, clipRect);
        }
    }

    public class AvaloniaHost : FCHost
    {
        /// <summary>
        /// 是否可以操作
        /// </summary>
        protected bool m_allowOperate = true;

        /// <summary>
        /// 是否支持局部绘图
        /// </summary>
        protected bool m_allowPartialPaint = true;

        /// <summary>
        /// 线程状态
        /// </summary>
        public int m_threadState = 0;

        /// <summary>
        /// 秒表信息
        /// </summary>
        private HashMap<int, AvaloniaTimer> m_timers = new HashMap<int, AvaloniaTimer>();

        public UserControl m_view;

        /// <summary>
        /// 获取是否允许操作
        /// </summary>
        public override bool allowOperate()
        {
            return m_allowOperate;
        }

        /// <summary>
        /// 获取是否允许局部绘图
        /// </summary>
        public override bool allowPartialpaint()
        {
            return m_allowPartialPaint;
        }

        public bool m_isDeleted;

        /// <summary>
        /// 获取是否已被销毁
        /// </summary>
        public override bool isDeleted()
        {
            return m_isDeleted;
        }

        /// <summary>
        /// 在视图的线程中调用方法
        /// </summary>
        /// <param name="view">视图</param>
        /// <param name="args">参数</param>
        public override void beginInvoke(FCView view, object args)
        {
            Avalonia.Threading.Dispatcher.UIThread.InvokeAsync(() =>
            {
                view.onInvoke(args);
            });
        }

        /// <summary>
        /// 复制文本
        /// </summary>
        /// <param name="text">文本</param>
        public override void copy(string text)
        {
        }

        /// <summary>
        /// 创建内部控件
        /// </summary>
        /// <param name="parent">父控件</param>
        /// <param name="clsid">控件标识</param>
        /// <returns>内部控件</returns>
        public override FCView createInternalView(FCView parent, String clsid)
        {
            switch (clsid)
            {
                case "datetitle":
                    {
                        FCCalendar calendar = parent as FCCalendar;
                        return new DateTitle(calendar);
                    }
                case "headdiv":
                    {
                        FCCalendar calendar = parent as FCCalendar;
                        HeadDiv headDiv = new HeadDiv(calendar);
                        headDiv.setWidth(parent.getWidth());
                        headDiv.setDock(FCDockStyle.Top);
                        return headDiv;
                    }
                case "lastbutton":
                    {
                        FCCalendar calendar = parent as FCCalendar;
                        return new ArrowButton(calendar);
                    }
                case "nextbutton":
                    {
                        FCCalendar calendar = parent as FCCalendar;
                        ArrowButton nextBtn = new ArrowButton(calendar);
                        nextBtn.setToLast(false);
                        return nextBtn;
                    }
                case "splitter":
                    {
                        ScrollButtonM splitter = new ScrollButtonM();
                        splitter.setBackColor(FCColor.rgba(0, 0, 0, 25));
                        splitter.setBorderColor(FCColor.rgba(200, 200, 200, 100));
                        splitter.setSize(new FCSize(5, 5));
                        return splitter;
                    }
                case "addbutton":
                    {
                        FCScrollBar scrollBar = parent as FCScrollBar;
                        scrollBar.setBorderColor(FCColor.None);
                        scrollBar.setBackColor(FCColor.None);
                        RibbonButton addButton = new RibbonButton();
                        addButton.setSize(new FCSize(15, 15));
                        if (scrollBar is FCHScrollBar)
                        {
                            addButton.ArrowType = 2;
                        }
                        else if (scrollBar is FCVScrollBar)
                        {
                            addButton.ArrowType = 4;
                        }
                        if (scrollBar is FCVScrollBar)
                        {
                            addButton.setHeight(0);
                        }
                        else if (scrollBar is FCHScrollBar)
                        {
                            addButton.setWidth(0);
                        }
                        return addButton;
                    }
                case "backbutton":
                    {
                        FCScrollBar scrollBar = parent as FCScrollBar;
                        scrollBar.setBorderColor(FCColor.None);
                        scrollBar.setBackColor(FCColor.None);
                        ScrollButtonM backButton = new ScrollButtonM();
                        backButton.setBorderColor(FCColor.None);
                        backButton.setBackColor(FCColor.None);
                        backButton.m_arrowType = 6;
                        return backButton;
                    }
                case "scrollbutton":
                    {
                        FCScrollBar scrollBar = parent as FCScrollBar;
                        scrollBar.setBorderColor(FCColor.None);
                        scrollBar.setBackColor(FCColor.None);
                        ScrollButtonM scrollButton = new ScrollButtonM();
                        scrollButton.setAllowDrag(true);
                        scrollButton.setBackColor(FCColor.rgba(94, 102, 115, 200));
                        scrollButton.setBorderColor(FCColor.None);
                        scrollButton.setCornerRadius(4);
                        scrollButton.m_arrowType = 5;
                        return scrollButton;
                    }
                case "reducebutton":
                    {
                        FCScrollBar scrollBar = parent as FCScrollBar;
                        scrollBar.setBorderColor(FCColor.None);
                        scrollBar.setBackColor(FCColor.None);
                        RibbonButton reduceButton = new RibbonButton();
                        reduceButton.setSize(new FCSize(15, 15));
                        if (scrollBar is FCHScrollBar)
                        {
                            reduceButton.ArrowType = 1;
                        }
                        else if (scrollBar is FCVScrollBar)
                        {
                            reduceButton.ArrowType = 3;
                        }
                        if (scrollBar is FCVScrollBar)
                        {
                            reduceButton.setHeight(0);
                        }
                        else if (scrollBar is FCHScrollBar)
                        {
                            reduceButton.setWidth(0);
                        }
                        return reduceButton;
                    }
                case "headerbutton":
                    {
                        RibbonButton button = new RibbonButton();
                        button.setAllowDrag(true);
                        FCSize size = new FCSize(100, 20);
                        button.setSize(size);
                        return button;
                    }
                case "dropdownbutton":
                    {
                        FCComboBox comboBox = parent as FCComboBox;
                        if (comboBox != null)
                        {
                            RibbonButton dropDownButton = new RibbonButton();
                            dropDownButton.ArrowType = 4;
                            dropDownButton.setDisplayOffset(false);
                            int width = comboBox.getWidth();
                            int height = comboBox.getHeight();
                            FCPoint location = new FCPoint(width - 20, 0);
                            dropDownButton.setLocation(location);
                            FCSize size = new FCSize(20, height);
                            dropDownButton.setSize(size);
                            return dropDownButton;
                        }
                        //日期选择
                        FCDateTimePicker datePicker = parent as FCDateTimePicker;
                        if (datePicker != null)
                        {
                            RibbonButton dropDownButton = new RibbonButton();
                            dropDownButton.ArrowType = 4;
                            dropDownButton.setDisplayOffset(false);
                            int width = datePicker.getWidth();
                            int height = datePicker.getHeight();
                            FCPoint location = new FCPoint(width - 16, 0);
                            dropDownButton.setLocation(location);
                            FCSize size = new FCSize(16, height);
                            dropDownButton.setSize(size);
                            return dropDownButton;
                        }
                        break;
                    }
                case "dropdownmenu":
                    {
                        //下拉列表
                        FCComboBox comboBox = parent as FCComboBox;
                        if (comboBox != null)
                        {
                            FCComboBoxMenu comboBoxMenu = new FCComboBoxMenu();
                            comboBoxMenu.setComboBox(comboBox);
                            comboBoxMenu.setPopup(true);
                            FCSize size = new FCSize(100, 200);
                            comboBoxMenu.setSize(size);
                            return comboBoxMenu;
                        }
                        //日期选择
                        FCDateTimePicker datePicker = parent as FCDateTimePicker;
                        if (datePicker != null)
                        {
                            FCMenu dropDownMenu = new FCMenu();
                            dropDownMenu.setPadding(new FCPadding(1));
                            dropDownMenu.setPopup(true);
                            FCSize size = new FCSize(200, 200);
                            dropDownMenu.setSize(size);
                            return dropDownMenu;
                        }
                        break;
                    }
                case "downbutton":
                    {
                        FCButton downButton = new FCButton();
                        downButton.setDisplayOffset(false);
                        downButton.setText("-");
                        FCSize size = new FCSize(16, 16);
                        downButton.setSize(size);
                        return downButton;
                    }
                case "upbutton":
                    {
                        FCButton upButton = new FCButton();
                        upButton.setDisplayOffset(false);
                        upButton.setText("+");
                        FCSize size = new FCSize(16, 16);
                        upButton.setSize(size);
                        return upButton;
                    }
                case "hscrollbar":
                    {
                        FCHScrollBar hScrollBar = new FCHScrollBar();
                        hScrollBar.setVisible(false);
                        hScrollBar.setSize(new FCSize(10, 10));
                        return hScrollBar;
                    }
                case "vscrollbar":
                    {
                        FCVScrollBar vScrollBar = new FCVScrollBar();
                        vScrollBar.setVisible(false);
                        vScrollBar.setSize(new FCSize(10, 10));
                        return vScrollBar;
                    }
                case "edittextbox":
                    {
                        FCTextBox textBox = new FCTextBox();
                        textBox.setFont(new FCFont("Default", 14, false, false, false));
                        textBox.setPadding(new FCPadding(0, 0, 0, 0));
                        return textBox;
                    }
            }
            return null;
        }

        /// <summary>
        /// 销毁资源
        /// </summary>
        public override void delete()
        {
            if (!m_isDeleted)
            {
                m_threadState = 0;
                m_isDeleted = true;
            }
        }

        /// <summary>
        /// 获取光标
        /// </summary>
        /// <returns>光标</returns>
        public override FCCursors getCursor()
        {
            return FCCursors.Arrow;
        }

        /// <summary>
        /// 获取鼠标位置
        /// </summary>
        /// <returns>坐标</returns>
        public FCPoint getMousePoint()
        {
            FCPoint mp = new FCPoint();
            return mp;
        }

        /// <summary>
        /// 获取矩形相交区
        /// </summary>
        /// <param name="lpDestRect">相交矩形</param>
        /// <param name="lpSrc1Rect">矩形1</param>
        /// <param name="lpSrc2Rect">矩形2</param>
        /// <returns>是否相交</returns>
        public override int getIntersectRect(ref FCRect lpDestRect, ref FCRect lpSrc1Rect, ref FCRect lpSrc2Rect)
        {
            lpDestRect.left = Math.Max(lpSrc1Rect.left, lpSrc2Rect.left);
            lpDestRect.right = Math.Min(lpSrc1Rect.right, lpSrc2Rect.right);
            lpDestRect.top = Math.Max(lpSrc1Rect.top, lpSrc2Rect.top);
            lpDestRect.bottom = Math.Min(lpSrc1Rect.bottom, lpSrc2Rect.bottom);
            if (lpDestRect.right > lpDestRect.left && lpDestRect.bottom > lpDestRect.top)
            {
                return 1;
            }
            else
            {
                lpDestRect.left = 0;
                lpDestRect.right = 0;
                lpDestRect.top = 0;
                lpDestRect.bottom = 0;
                return 0;
            }
        }

        protected FCNative m_native;

        /// <summary>
        /// 获取方法库
        /// </summary>
        public override FCNative getNative()
        {
            return m_native;
        }

        /// <summary>
        /// 获取尺寸
        /// </summary>
        /// <returns>大小</returns>
        public override FCSize getSize()
        {
            return new FCSize(m_native.getSize().cx, m_native.getSize().cy);
        }

        /// <summary>
        /// 触摸位置
        /// </summary>
        public FCPoint m_touchPoint = new FCPoint();

        /// <summary>
        /// 获取触摸位置
        /// </summary>
        /// <returns>坐标</returns>
        public override FCPoint getTouchPoint()
        {
            return m_touchPoint;
        }

        /// <summary>
        /// 获取矩形并集区
        /// </summary>
        /// <param name="lpDestRect">并集矩形</param>
        /// <param name="lpSrc1Rect">矩形1</param>
        /// <param name="lpSrc2Rect">矩形2</param>
        /// <returns>是否相交</returns>
        public override int getUnionRect(ref FCRect lpDestRect, ref FCRect lpSrc1Rect, ref FCRect lpSrc2Rect)
        {
            return 0;
        }

        /// <summary>
        /// 刷新绘图
        /// </summary>
        public override void invalidate()
        {
            if (m_view != null)
            {
                m_view.InvalidateVisual();
            }
        }

        /// <summary>
        /// 刷新绘图
        /// </summary>
        /// <param name="rect">区域</param>
        public override void invalidate(FCRect rect)
        {
            if (m_view != null)
            {
                m_view.InvalidateVisual();
            }
        }

        /// <summary>
        /// 在视图的线程中调用方法
        /// </summary>
        /// <param name="view">视图</param>
        /// <param name="args">参数</param>
        public override void invoke(FCView view, object args)
        {
            Avalonia.Threading.Dispatcher.UIThread.InvokeAsync(() =>
            {
                view.onInvoke(args);
            });
        }

        /// <summary>
        /// 获取按键的状态
        /// </summary>
        /// <param name="key">按键</param>
        /// <returns>状态</returns>
        public override bool isKeyPress(int key)
        {
            return false;
        }

        // <summary>
        /// 启动检查线程
        /// </summary>
        public void invokeThread()
        {
            m_threadState = 1;
            while (m_threadState == 1)
            {
                try
                {
                    onTimer();
                    Thread.Sleep(10);
                }
                catch (Exception e)
                {
                }
            }
            m_threadState = 3;
        }

        ///秒表方法
        public void onTimer()
        {
            if (m_native != null)
            {
                if (m_view != null)
                {
                    ArrayList<int> m_runningTimerIDs = new ArrayList<int>();
                    lock (m_timers)
                    {
                        try
                        {
                            foreach (AvaloniaTimer timer in m_timers.Values)
                            {
                                if (timer.m_tick % timer.m_interval == 0)
                                {
                                    m_runningTimerIDs.add(timer.m_timerID);
                                }
                                timer.m_tick++;
                            }
                        }
                        catch (Exception ex)
                        {

                        }
                    }
                    if (m_runningTimerIDs.size() > 0)
                    {
                        Avalonia.Threading.Dispatcher.UIThread.InvokeAsync(() =>
                        {
                            lock (m_timers)
                            {
                                try
                                {
                                    int runningTimerIDsSize = m_runningTimerIDs.size();
                                    for (int i = 0; i < runningTimerIDsSize; i++)
                                    {
                                        m_native.onTimer(m_runningTimerIDs.get(i));
                                    }
                                    m_runningTimerIDs.clear();
                                }
                                catch (Exception ex)
                                {
                                }
                            }
                        });
                    }
                }
            }
        }

        /// <summary>
        /// 获取粘贴文本
        /// </summary>
        /// <returns>文本</returns>
        public override string paste()
        {
            return "";
        }

        /// <summary>
        /// 设置是否允许操作
        /// </summary>
        public override void setAllowOperate(bool value)
        {
            m_allowOperate = value;
        }

        /// <summary>
        /// 设置是否允许局部绘图
        /// </summary>
        public override void setAllowPartialPaint(bool value)
        {
            m_allowPartialPaint = value;
        }

        /// <summary>
        /// 设置光标
        /// </summary>
        /// <param name="cursor">光标</param>
        public override void setCursor(FCCursors cursor)
        {
        }

        /// <summary>
        /// 设置方法库
        /// </summary>
        public override void setNative(FCNative value)
        {
            m_native = value;
        }

        /// <summary>
        /// 设置触摸位置
        /// </summary>
        public override void setTouchPoint(FCPoint point)
        {
            m_touchPoint = point;
        }

        /// <summary>
        /// 显示提示框
        /// </summary>
        /// <param name="text">文字</param>
        /// <param name="mp">位置</param>
        public override void showToolTip(string text, FCPoint mp)
        {
        }

        /// <summary>
        /// 开启秒表
        /// </summary>
        /// <param name="timerID">秒表ID</param>
        /// <param name="interval">间隔</param>
        public override void startTimer(int timerID, int interval)
        {
            interval = interval / 10;
            if (interval < 1)
            {
                interval = 1;
            }
            lock (m_timers)
            {
                if (m_timers.containsKey(timerID))
                {
                    AvaloniaTimer timer = m_timers.get(timerID);
                    timer.m_interval = interval;
                    timer.m_tick = 0;
                }
                else
                {
                    AvaloniaTimer timer = new AvaloniaTimer();
                    timer.m_interval = interval;
                    timer.m_timerID = timerID;
                    m_timers.put(timerID, timer);
                }
            }
        }

        /// <summary>
        /// 停止秒表
        /// </summary>
        /// <param name="timerID">秒表ID</param>
        public override void stopTimer(int timerID)
        {
            lock (m_timers)
            {
                if (m_timers.containsKey(timerID))
                {
                    m_timers.remove(timerID);
                }
            }
        }

        /// <summary>
        /// 设置视图
        /// </summary>
        /// <param name="view"></param>
        public void setView(UserControl view)
        {
            m_view = view;
            Thread tThread = new Thread(new ThreadStart(invokeThread));
            tThread.Start();
        }
    }

    /// <summary>
    /// 秒表信息
    /// </summary>
    public class AvaloniaTimer
    {
        /// <summary>
        /// 间隔
        /// </summary>
        public int m_interval;

        /// <summary>
        /// 计时
        /// </summary>
        public int m_tick;

        /// <summary>
        /// ID
        /// </summary>
        public int m_timerID;
    }
}
